using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace TamTam.SharePoint.Diagnostics {

    /// <summary>
    /// Logging wrapper to log to the Moss 2007 Log location, adhering to the moss 2007 log file settings.
    /// </summary>
    /// <remarks>
    /// by Stef van Hooijdonk, Tam Tam BV, 2007
    /// </remarks>
    public class Logging {

        internal string LogFile = null;
        internal string LineToLog = null;

        /// <summary>
        /// This will actually log the content to the actual file.
        /// </summary>
        /// <remarks>Should be called by the <c>SPSecurity.RunWithElevatedPrivileges</c></remarks>
        internal void Write() {
            string actualfilename = Logging.GetCurrentLogFile(this.LogFile);
            using (System.IO.StreamWriter file = System.IO.File.AppendText(actualfilename)) {
                file.WriteLine(this.LineToLog);
                file.Flush();
            }
        }

        /// <summary>
        /// Log an exception to <c>logfile</c>
        /// </summary>
        /// <param name="logfile">the base name of the logfile to log to logfile-datetimestamp.log</param>
        /// <param name="exc">The exception to log</param>
        public static void LogException(string logfile,
            Exception exc) {
            string line = string.Format("{0}\r\n{1}", exc.Message, exc.StackTrace);
            Logging.LogMessage(
                logfile,
                exc.GetType().ToString(),
                line);
        }
        /// <summary>
        /// Log a message to <c>logfile</c>
        /// </summary>
        /// <param name="logfile">the base name of the logfile to log to logfile-datetimestamp.log</param>
        /// <param name="category">a category to log</param>
        /// <param name="message">the message to log</param>
        public static void LogMessage(string logfile,
            string category,
            string message) {

            if (logfile != null) {
                Logging l = new Logging();
                l.LogFile = logfile;
                l.LineToLog = string.Format("{0}\t{1}\t{2}",
                        DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss"),
                        category.PadLeft(25),
                        message);
                // this way we can always write to the logfiles
                SPSecurity.CodeToRunElevated log = new SPSecurity.CodeToRunElevated(l.Write);
                SPSecurity.RunWithElevatedPrivileges(log);
            }
        }

        private const string LogExtention = ".log";

        /// <summary>
        /// Parse/handle/cleanup the logfiles for the baselogname <c>logfile</c>
        /// </summary>
        /// <param name="logfile">the basename for the logfiles</param>
        /// <returns>the actual filename to log to</returns>
        private static string GetCurrentLogFile(string logfile) {
            string timestamp = DateTime.Now.AddMinutes(-SPDiagnosticsService.Local.LogCutInterval).ToString("yyyyMMdd-HHmm");


            string lastallowedlogfilename = System.IO.Path.Combine(
                SPDiagnosticsService.Local.LogLocation,
                 logfile + "-" + timestamp + Logging.LogExtention);
            // get existing logfiles
            string[] files = System.IO.Directory.GetFiles(SPDiagnosticsService.Local.LogLocation, logfile + "*.log", System.IO.SearchOption.TopDirectoryOnly);

            System.Collections.ArrayList list = new System.Collections.ArrayList();
            list.AddRange(files);

            // clean up old log files
            if (list.Count > SPDiagnosticsService.Local.LogsToKeep) {
                int count = list.Count;
                while (count > SPDiagnosticsService.Local.LogsToKeep) {
                    System.IO.File.Delete(list[0] as string);
                    count--;
                }
            }
            // lookup current logfile
            string currentLogFile = "";
            if (list.Count > 0) {
                string lastfile = list[list.Count - 1] as string;
                if (string.Compare(lastfile, lastallowedlogfilename) > 0)
                    currentLogFile = lastfile;
            }
            // create a new logfile
            if (currentLogFile == "") {
                string timestampn = DateTime.Now.ToString("yyyyMMdd-HHmm");
                currentLogFile = System.IO.Path.Combine(
                    SPDiagnosticsService.Local.LogLocation,
                     logfile + "-" + timestampn + Logging.LogExtention);
            }
            return currentLogFile;
        }
    }
}
